package recursivecode.trymodel.left2right;

import java.util.HashSet;
import java.util.Set;

/**
 * 功能描述:数字转移字  111 -> ak 或者 ka
 * 2024/07/15
 *
 * @author ZhangYi
 */
public class NumberTransferWords {
	/**
	 * 字符长度0
	 */
	private final static char CHAR_LENGTH_0 = '0';
	/**
	 * 字符长度1
	 */
	private final static char CHAR_LENGTH_1 = '1';
	/**
	 * 字符长度2
	 */
	private final static char CHAR_LENGTH_2 = '2';
	/**
	 * 炭化长度6
	 */
	private static final char CHAR_LENGTH_6 = '6';


	public static void main(String[] args) {
		String str = "123";
		System.out.println(transfer(str));
		System.out.println(getTransferCount(str));
		System.out.println(getTransferCountFromCache(str));
	}

	private static int getTransferCountFromCache(String str) {
		if (str == null || str.length() == 0) {
			return 0;
		}
		char[] chars = str.toCharArray();
		int N = chars.length;
		int[] dp = new int[N + 1];
		dp[N] = 1;

		for (int index = N-1;index>=0;index--){

			// 如果是1 开头,那么可以和任意数字组合 1n ,不会超过26
			if (chars[index] == CHAR_LENGTH_1) {
				dp[index] = dp[index + 1];
				// 越界检测,如果没有越界就下一个
				if (index + 1 < chars.length) {
					dp[index] += dp[index + 2];
				}
			}else if (chars[index] == CHAR_LENGTH_2) {
				// 如果是2开头, 那么可以和0-6组合,不会超过26
				dp[index] = dp[index + 1];
				if (index + 1 < chars.length
						&& (chars[index + 1] >= CHAR_LENGTH_0 && chars[index + 1] <= CHAR_LENGTH_6)) {
					dp[index] += dp[index + 2];
				}
			}else {
				dp[index] = dp[index+1];
			}
		}

		return dp[0];

	}

	/**
	 * 获取转换后的计数
	 *
	 * @param str str
	 * @return int
	 * @author ZhangYi
	 */
	private static int getTransferCount(String str) {
		if (str == null || str.length() == 0) {
			return 0;
		}

		return getTransferCount(str.toCharArray(), 0);
	}

	/**
	 * 获取转换后的计数
	 *
	 * @param chars 字符
	 * @param index 索引
	 * @return int
	 * @author ZhangYi
	 */
	private static int getTransferCount(char[] chars, int index) {
		// 递归终止条件,到达了字符串的结尾了,说明这个字符是有效的, 这里就是一个终结符的判断,如果结束了,就返回1
		if (index == chars.length) {
			return 1;
		}
		// 0开头的情况, 不可以发起组合操作, 此路径是无效的字符操作,直接返回0 ;
		if (chars[index] == CHAR_LENGTH_0) {
			return 0;
		}
		// 如果是1 开头,那么可以和任意数字组合 1n ,不会超过26
		if (chars[index] == CHAR_LENGTH_1) {
			int result = getTransferCount(chars, index + 1);
			// 越界检测,如果没有越界就下一个
			if (index + 1 < chars.length) {
				result += getTransferCount(chars, index + 2);
			}
			return result;
		}
		// 如果是2开头, 那么可以和0-6组合,不会超过26
		if (chars[index] == CHAR_LENGTH_2) {
			int result = getTransferCount(chars, index + 1);
			if (index + 1 < chars.length
					&& (chars[index + 1] >= CHAR_LENGTH_0 && chars[index + 1] <= CHAR_LENGTH_6)) {
				result += getTransferCount(chars, index + 2);
			}
			return result;
		}

		// 如果是3~9的时候,直接下一个, 3n~9n 会超过26
		return getTransferCount(chars, index + 1);

	}

	/**
	 * 转换
	 *
	 * @param str str
	 * @return {@code Set<String> }
	 * @author ZhangYi
	 */
	private static Set<String> transfer(String str) {
		if (str == null || str.length() == 0) {
			return new HashSet<>();
		}
		HashSet<String> result = new HashSet<>();
		char[] chars = str.toCharArray();
		processTransfer(chars, 0, "", result);
		return result;

	}

	private static void processTransfer(char[] chars, int index, String path, HashSet<String> result) {
		if (index == chars.length) {
			result.add(path);
			return;
		}
		if (chars[index] == CHAR_LENGTH_0) {
			return;
		}

		// 1 开头的情况, 可以和任意数字组合 1n ,不会超过26
		if (chars[index] == CHAR_LENGTH_1) {
			processTransfer(chars, index + 1, path + numberTransfer(String.valueOf(chars[index])), result);
			if (index + 1 < chars.length) {
				processTransfer(chars, index + 2, path + numberTransfer(String.valueOf(chars[index]) + String.valueOf(chars[index + 1])), result);
			}
		}
		// 2开头的情况, 只可以和 0-6组合, 不会超过26
		if (chars[index] == CHAR_LENGTH_2) {
			processTransfer(chars, index + 1, path + numberTransfer(String.valueOf(chars[index])), result);
			if (index + 1 < chars.length
					&& (chars[index + 1] >= CHAR_LENGTH_0 && chars[index + 1] <= CHAR_LENGTH_6)) {
				processTransfer(chars, index + 2, path + numberTransfer(String.valueOf(chars[index]) + String.valueOf(chars[index + 1])), result);
			}

		}

		// 3~9的时候 直接下一个,不可以发起 组合 操作, 因为 3n~9n 是不能够转换任意的字符的
		processTransfer(chars, index + 1, path + numberTransfer(String.valueOf(chars[index])), result);
	}

	private static String numberTransfer(String aChar) {
		return CharacterEnum.getValueByKey(aChar);
	}

}
